#include <jni.h>
#include <string>
#include <android/log.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Platform.h>
using namespace std;
#define LOGD(TAG,...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
#define LOGE(TAG,...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)
#define fTAG "ffmpeg"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>

jstring
Java_com_tzztn_ffmpegdemo_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

jstring
Java_com_tzztn_ffmpegdemo_MainActivity_urlprotocolinfo(
        JNIEnv *env, jobject) {
    char info[40000] = {0};

    struct URLProtocol *pup = nullptr;

    struct URLProtocol **p_temp = &pup;
    avio_enum_protocols((void **) p_temp, 0);

    while ((*p_temp) != nullptr) {
        sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 0));
    }
    pup = nullptr;
    avio_enum_protocols((void **) p_temp, 1);
    while ((*p_temp) != nullptr) {
        sprintf(info, "%sInput: %s\n", info, avio_enum_protocols((void **) p_temp, 1));
    }
    return env->NewStringUTF(info);
}

jstring
Java_com_tzztn_ffmpegdemo_MainActivity_avformatinfo(
        JNIEnv *env, jobject) {
    char info[40000] = {0};
    void *i = nullptr,*j = nullptr;
    const AVInputFormat *if_temp;
    const AVOutputFormat *of_temp;
    while ((if_temp = av_demuxer_iterate(&i)) != nullptr) {
        sprintf(info, "%sInput: %s\n", info, if_temp->name);
    }
    while ((of_temp = av_muxer_iterate(&j)) != nullptr) {
        sprintf(info, "%sOutput: %s\n", info, of_temp->name);
    }
    return env->NewStringUTF(info);
}

jstring
Java_com_tzztn_ffmpegdemo_MainActivity_avcodecinfo(
        JNIEnv *env, jobject) {
    char info[40000] = {0};
    void *i = nullptr;
    const AVCodec *c_temp= nullptr;
    while ((c_temp=av_codec_iterate(&i)) != nullptr) {
        if (c_temp->decode != nullptr) {
            sprintf(info, "%sdecode:", info);
        } else {
            sprintf(info, "%sencode:", info);
        }
        switch (c_temp->type) {
            case AVMEDIA_TYPE_VIDEO:
                sprintf(info, "%s(video):", info);
                break;
            case AVMEDIA_TYPE_AUDIO:
                sprintf(info, "%s(audio):", info);
                break;
            default:
                sprintf(info, "%s(other):", info);
                break;
        }
        sprintf(info, "%s[%10s]\n", info, c_temp->name);
    }

    return env->NewStringUTF(info);
}

jstring
Java_com_tzztn_ffmpegdemo_MainActivity_avfilterinfo(
        JNIEnv *env, jobject) {
    void *i = nullptr;
    const AVFilter *f_temp;
    char info[100000]={0};

    while((f_temp=(AVFilter *)av_filter_iterate(&i)) != nullptr) {
        sprintf(info,"%s%s\n",info,f_temp->name);
    }
    return env->NewStringUTF(info);
}


}